/*----------------------------------------------------------------------------
 * Copyright (c) <2016-2020>, <Huawei Technologies Co., Ltd>
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific prior written
 * permission.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
 * Notice of Export Control Law
 * ===============================================
 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might
 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located.
 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such
 * applicable export control laws and regulations.
 *---------------------------------------------------------------------------*/
#include "ble.h"
#include "ble_uart.h"
#include "osal.h"
#include "los_config.h"
#include "los_task.h"
#include "los_queue.h"
#include "securec.h"
#include "omip.h"
#include "omip_log.h"
#include "hlink_user_api.h"
#include "hardware_com.h"


int user_task(unsigned char* data, unsigned int messageId)
{
    UINT32 ret = 0;
    cJSON * root = NULL;
    root = cJSON_Parse((char *)data);
    if(root != NULL)
    {
        printf("user_parse_data: %s\r\n\r\n", cJSON_PrintUnformatted(root));
        if(cJSON_GetObjectItem(root, "srv") != NULL && strcmp(cJSON_GetObjectItem(root, "srv")->valuestring,"sn") == 0)
        {
            unsigned char str[] = "{\"sn\":{\"DDC\":\"HL109085002100233631\"}}";
            if(ble_api_send(0, 0x12, str, strlen((char *)str)) == BLE_OK)
                printf("send sn success: \r\n");
        }
        if(cJSON_GetObjectItem(root, "cmd") != NULL && strcmp(cJSON_GetObjectItem(root, "cmd")->valuestring, "set") == 0)
            ble_api_send(messageId,CMD_RESPOND,NULL,4);
    }
    cJSON_Delete(root);
    return ret;
}

cJSON *make_ble_respond_json(int iMid,int iStatus,int iErrCode) //构造回复蓝牙HLINK模块的JSON数据
{
	cJSON *pRetJson =cJSON_CreateObject();
	cJSON_AddItemToObject(pRetJson,"mid",cJSON_CreateNumber(iMid));
	cJSON_AddItemToObject(pRetJson,"status",cJSON_CreateNumber(iStatus));
	cJSON_AddItemToObject(pRetJson,"errcode", cJSON_CreateNumber(iErrCode));
	return pRetJson;
}

int mcu_general_send_ble(unsigned short iCmd,unsigned char iFormat,unsigned char *pLoadData,unsigned int iDataLen) //向蓝牙HLINK发送数据
{
	omip_transaction send_ts = {0};
	send_ts.vc =OMIP_VC_CHANNEL6;
	send_ts.relay_flag =0;
	send_ts.relay_vc =0;
	send_ts.ctf =iFormat; //OMIP_CONTENT_FORMAT_JSON;
	send_ts.timeout =OMIP_SEND_DEFAULT; 	//default 2s
	send_ts.ext_io_flag =OMIP_ENCODE_EXT;	//when send to BLE, must chose this
	send_ts.cmd =iCmd;
	send_ts.data=pLoadData;
	send_ts.len =iDataLen;
	return omip_send(&send_ts);
}

int mcu_send_json_ble(unsigned short iCmd,cJSON *pJson,int iFree) //向蓝牙HLINK发送JSON数据
{
	char *pData =(pJson?cJSON_PrintUnformatted(pJson):NULL);
	OMIP_LOG_INFO("send to ble,cmd:0x%04X,data:%s\r\n",iCmd,(pData?pData:""));
	int iSend =mcu_general_send_ble(iCmd,OMIP_CONTENT_FORMAT_JSON,(unsigned char *)(pData?pData:""),(pData?strlen(pData):0));
	if(pData) omip_free(pData);
	if(iFree !=0 && pJson) cJSON_Delete(pJson);
	return iSend;
}

int set_ble_name(char *pSnStr) //设置蓝牙名称
{
	int  sn_len =strlen(pSnStr);
	char ble_name[24+1] = {0x02,0xFF,0x14,0x00,0x13,0x09,'h','l','i','n','k','-',0x00}; //ble cmd:FF02,len:000e,payload:...
	memcpy(ble_name+12,&(pSnStr[sn_len>=12?(sn_len-12):0]),sn_len>=12?12:sn_len);
	OMIP_LOG_INFO("this ble name:%s\r\n",&ble_name[6]);
	omip_transaction send_ts = {0};
	send_ts.vc =OMIP_VC_CHANNEL6;
	send_ts.relay_flag =0;
	send_ts.relay_vc =0;
	send_ts.ctf =OMIP_CONTENT_FORMAT_BINARY;
	send_ts.timeout =OMIP_SEND_DEFAULT; 	//default 2s
	send_ts.ext_io_flag =OMIP_NOT_ENCODE;
	send_ts.cmd =HLINK_CMD_BLE_CMD;
	send_ts.data=(unsigned char *)ble_name;
	send_ts.len =24;
	return omip_send(&send_ts);
}

unsigned int ble_set_wifi(unsigned char* data, unsigned int len)
{
    cJSON *root =cJSON_Parse((char *)data);
	if(!root) return 0;
	cJSON *pJsParas = cJSON_GetObjectItem(root,"paras");
	if(pJsParas) cJSON_DeleteItemFromObject(pJsParas,"pwd"); //删除密码区域再打印
	cJSON *pJsMid = cJSON_GetObjectItem(root,"mid");
    int mid =(pJsMid?pJsMid->valueint:0);
	char *pJsNetCfg = cJSON_PrintUnformatted(root);
	printf("[%s:%d]set wifi cfg: %s\r\n",__FUNCTION__,__LINE__,pJsNetCfg);
	omip_free(pJsNetCfg);
	cJSON_Delete(root);
	int iSendRet =omip_api_send(OMIP_VC_DEFAULT0,OMIP_CONTENT_FORMAT_JSON,HLINK_CMD_SET_MODULE_CONF,(unsigned char *)data,(unsigned short)len);
	if(iSendRet ==OMIP_OK)
    {
        ble_api_send(mid,CMD_RESPOND,NULL,4);
        wifi_reset_delay(); //WIFI模块延时复位
    }
    else
    {
        printf("[%s:%d]send wifi cfg failed!\r\n",__FUNCTION__,__LINE__);
    }
	return 1;
}

unsigned int ble_get_wifi(unsigned char* data, unsigned int len)
{
    cJSON *root =cJSON_Parse((char *)data);
	cJSON *pJsMid =(root?cJSON_GetObjectItem(root,"mid"):NULL);
	int mid =(pJsMid?pJsMid->valueint:0);
	char *pJsNetCfg = (root?cJSON_PrintUnformatted(root):NULL);
	printf("[%s:%d]get wifi cfg: %s\r\n",__FUNCTION__,__LINE__,(pJsNetCfg?pJsNetCfg:"<NULL>"));
	if(pJsNetCfg) omip_free(pJsNetCfg);
	if(root) cJSON_Delete(root);
	int iSendRet =omip_api_send(OMIP_VC_DEFAULT0,OMIP_CONTENT_FORMAT_JSON,HLINK_CMD_GET_MODULE_CONF,(unsigned char *)data,(unsigned short)len);
	if(iSendRet ==OMIP_OK)
    {
        ble_api_send(mid,CMD_RESPOND,NULL,4);
    }
    else
    {
        printf("[%s:%d]send get wifi failed!\r\n",__FUNCTION__,__LINE__);
    }
	return 1;
}

int ble_main()
{
    unsigned char cmd = 0;
    unsigned char *data = osal_malloc(oneFrameDataSize);
    unsigned int len = 0;
    unsigned int messageId = 0;
    unsigned char ble_name[]={0x02, 0xff, 0x0e, 0x00, 0x0d, 0x09, 'h', 'l', 'i', 'n', 'k', '-',0x38, 0x38, 0x38, 0x38, 0x38, 0x38};
    osal_task_sleep(1000);
    ble_api_send(messageId, CMD_BLE, ble_name, sizeof(ble_name));
    while(1)
    {
        len = ble_api_recv(&messageId, &cmd, data, oneFrameDataSize);
        if( len != 0)
        {
            printf("demo: messageId: %d ret: %04x cmd: %02x\r\n", messageId, len, cmd);
            user_task(data, messageId);
            ble_set_wifi(data, messageId);
        }
        osal_task_sleep(10);
    }
}

int ble_task_start(void)
{
    int ret = -1;
    ble_uart_init();
    ble_init();
    UINT32 uwRet = LOS_OK;
    UINT32  handle;
    TSK_INIT_PARAM_S task_init_param;
    memset (&task_init_param, 0, sizeof (TSK_INIT_PARAM_S));
    task_init_param.uwArg = (unsigned int)NULL;
    task_init_param.usTaskPrio = 23;
    task_init_param.pcName =(char *) "ble_main";
    task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)ble_main;
    task_init_param.uwStackSize = 0x1000;
    uwRet = LOS_TaskCreate(&handle, &task_init_param);
    if(LOS_OK == uwRet){
        ret = 0;
    }
    return ret;
}

